home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 59454 / 59454.xpi / content / util / Utils.js < prev   
Text File  |  2010-01-14  |  11KB  |  395 lines

  1. /* 
  2.  * Import Module.js before using this file.
  3.  */
  4.  
  5. // create a namespace for our Utils.
  6. var BartUtils = BartModule.createNamespace("bart.ibrowser.Utils");
  7.  
  8. /**
  9.  * clip a string to a fixed length. If length is not specified, use 15 as default.
  10.  * If a string is clipped, it's followed with a "...".
  11.  * If text is null or undefined or empty, return the original value.
  12.  * Throw an error if text is not a string, or length <=0
  13.  */
  14. BartUtils.clipText = function(text, length)
  15. {
  16.     if(!text)
  17.     {
  18.         // return the original value
  19.         return text;
  20.     }
  21.  
  22.     //
  23.     if((typeof text != "string"))
  24.     {
  25.         throw new Error("text required");
  26.     }
  27.  
  28.     if(length <= 0)
  29.     {
  30.         throw new Error("length should be greater than 0");
  31.     }
  32.  
  33.     if(typeof length == "undefined")
  34.     {
  35.         length = 15;
  36.     }
  37.  
  38.     var clippedText;
  39.     if(text.length > length)
  40.     {
  41.         clippedText = text.substr(0, length) + "...";
  42.     }
  43.     else
  44.     {
  45.         clippedText = text;
  46.     }
  47.  
  48.     return clippedText;
  49. };
  50.  
  51. /**
  52.  *  trim leading and trailing whitespace.
  53.  *  If text is null or undefined or empty, return the original value.
  54.  *  Throw an error if text type is not a string.
  55.  */
  56. BartUtils.trimText = function(text)
  57. {
  58.     if(!text)
  59.     {
  60.         return text;
  61.     }
  62.     if(typeof(text) != "string")
  63.     {
  64.         throw new Error("text required");
  65.     }
  66.  
  67.     text = text.replace(/^\s+/, '');
  68.     text = text.replace(/\s+$/, '');
  69.  
  70.     // and replace all conjuncted whitespaces with a single space
  71.     //text = text.replace(/\s+/g, ' ');
  72.  
  73.     return text;
  74. };
  75.  
  76. /**
  77.  * Log an error to Firefox's error console.
  78.  */
  79. BartUtils.logError = function(error)
  80. {
  81.     Components.utils.reportError(error);
  82. };
  83.  
  84. /**
  85.  * A utility function for defining javascript classes.
  86.  *
  87.  * This function expects a single object as its only argument.
  88.  * It defines a new JavaScript class based on the data and returns the constructor function of the new class.
  89.  *
  90.  * The object passed as an argument should have some or all of the following properties:
  91.  *
  92.  *  name:   The name of the class being defined.
  93.  *          If specified, this value will be stored in the classname property of the prototype object.
  94.  *
  95.  *  extend: The constructor of the class to be extended. If omitted. the Object() constructor will be used.
  96.  *          This value will be stored in the superclass property of the prototype object.
  97.  *
  98.  *  constructor:    The constructor function for the class. If omitted, a new empty function will be used.
  99.  *                  This value becomes the return value of the function, and is also stored in the constructor
  100.  *                  property of the prototype object.
  101.  *
  102.  *  methods:    An object that specifies the insstance methods (and other shared properties) for the class.
  103.  *              The properties of this object are copied into the prototype object of the class.
  104.  *              Properties named "classname", "superclass" and "constructor" are reserved and should not
  105.  *              be used in this object.
  106.  *
  107.  *  statics:    An object that specifies the static methods (and other static properties) for the class.
  108.  *              The properties of this object become properties of the constructor function.
  109.  */
  110. BartUtils.defineClass = function(data)
  111. {
  112.     var classname = data.name;
  113.     var superclass = data.extend || Object;
  114.     var constructor = data.construct || function(){};
  115.     var methods = data.methods || {};
  116.     var statics = data.statics || {};
  117.  
  118.     // create the prototype object that will become prototype for the result class
  119.     var proto = new superclass();
  120.  
  121.     for(var p in proto)
  122.     {
  123.         // delete any noninherited properties
  124.         if(proto.hasOwnProperty(p))
  125.         {
  126.             delete proto[p];
  127.         }
  128.     }
  129.  
  130.     // copy instance methods to the prototype object
  131.     for(var p in methods)
  132.     {
  133.         proto[p] = methods[p];
  134.     }
  135.  
  136.     proto.constructor = constructor;
  137.     proto.superclass = superclass;
  138.     if(classname)
  139.     {
  140.         proto.classname = classname;
  141.     }
  142.  
  143.     // associate the prototype object with the constructor function
  144.     constructor.prototype = proto;
  145.  
  146.     // copy static properties to the constructor
  147.     for(var p in statics)
  148.     {
  149.         constructor[p] = statics[p];
  150.     }
  151.  
  152.     return constructor;
  153. };
  154.  
  155. /**
  156.  * Create an XMLHttpRequest object.
  157.  * The object passed as an argument should have some or all of the following properties:
  158.  * 
  159.  *  method: "GET" or "POST.
  160.  *  url: The url to which to send the request.
  161.  *  async: true or false. Default is true, indicating whether or not to perform the operation asynchronously.
  162.  *  body: This may be an nsIDocument, nsIInputStream, or a string (an nsISupportsString if called from native code)
  163.  *      that is used to populate the body of a POST request.
  164.  *  callback: callback function for "onreadystatechange" event if in async mode.
  165.  *
  166.  * This method will open the url and send data to that url if it's specified.
  167.  * 
  168.  * An Error will be thrown if error occurs.
  169.  */
  170. BartUtils.createXMLHttpRequest = function(data)
  171. {
  172.     var method = data.method || "GET";
  173.     var url = data.url;
  174.     var async = (data.async == undefined ? true : data.async);
  175.     var body = (data.body == undefined ? null : data.body);
  176.     var callback = data.callback;
  177.     var eventName = data.event || "onreadystatechange";
  178.     var mimeType = data.mimeType || "text/xml";
  179.  
  180.     var httpRequest = new XMLHttpRequest();
  181.     if(!httpRequest)
  182.     {
  183.         throw new Error("Failed to create XMLHttpRequest object.");
  184.     }
  185.  
  186.     if(httpRequest.overrideMimeType)
  187.     {
  188.         httpRequest.overrideMimeType(mimeType);
  189.     }
  190.  
  191.     if(callback)
  192.     {
  193.         //httpRequest.onreadystatechange = callback;
  194.         httpRequest.addEventListener(eventName, callback, false);
  195.     }
  196.  
  197.     if(url)
  198.     {
  199.         httpRequest.open(method, url, async);
  200.         httpRequest.send(body);
  201.     }
  202.  
  203.     return httpRequest;
  204. };
  205.  
  206. BartUtils.registerCss = function(cssText)
  207. {
  208.     var styleSheetService = Components.classes["@mozilla.org/content/style-sheet-service;1"]
  209.                                .getService(Components.interfaces.nsIStyleSheetService);
  210.     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  211.                                .getService(Components.interfaces.nsIIOService);
  212.  
  213.     var uri = ioService.newURI("data:text/css;base64," + btoa(cssText), null, null);
  214.     if(!styleSheetService.sheetRegistered(uri, styleSheetService.USER_SHEET))
  215.     {
  216.         styleSheetService.loadAndRegisterSheet(uri, styleSheetService.USER_SHEET);
  217.     }
  218. };
  219.  
  220. /**
  221.  * Load a local file. filePath should have pattern: chrome://ExtensionName/...filename.
  222.  * callback should be a function, signature is: func(event). Event target is an XMLHttpRequest object.
  223.  */
  224. BartUtils.loadLocalFile = function(filePath, mimeType, callback)
  225. {
  226.     BartUtils.createXMLHttpRequest(
  227.     {
  228.        url: filePath,
  229.        async: false,
  230.        event: "load",
  231.        mimeType: mimeType,
  232.        callback: function(event)
  233.                 {
  234.                     if(callback)
  235.                     {
  236.                         callback(event);
  237.                     }
  238.                 }
  239.     });
  240. };
  241. /*
  242. BartUtils.str2Hex = function(s)
  243. {
  244.     var c = "";
  245.     var n;
  246.     var ss = "0123456789ABCDEF";
  247.     var digS = "";
  248.     for(var i = 0; i < s.length; i ++)
  249.     {
  250.         c = s.charAt(i);
  251.         n = ss.indexOf(c);
  252.         digS += BartUtils.dec2Dig(eval(n));
  253.  
  254.     }
  255.     //return value;
  256.     return digS;
  257. };
  258.  
  259. BartUtils.dec2Dig = function(n1)
  260. {
  261.     var s = "";
  262.     var n2 = 0;
  263.     for(var i = 0; i < 4; i++)
  264.     {
  265.         n2 = Math.pow(2,3 - i);
  266.         if(n1 >= n2)
  267.         {
  268.             s += '1';
  269.             n1 = n1 - n2;
  270.         }
  271.         else
  272.             s += '0';
  273.  
  274.     }
  275.     return s;
  276. };
  277.  
  278. BartUtils.dig2Dec = function(s)
  279. {
  280.     var retV = 0;
  281.     if(s.length == 4)
  282.     {
  283.         for(var i = 0; i < 4; i ++)
  284.         {
  285.             retV += eval(s.charAt(i)) * Math.pow(2, 3 - i);
  286.         }
  287.         return retV;
  288.     }
  289.     return -1;
  290. };
  291.  
  292. BartUtils.hex2Utf8 = function(s)
  293. {
  294.     var retS = "";
  295.     var tempS = "";
  296.     var ss = "";
  297.     if(s.length == 16)
  298.     {
  299.         tempS = "1110" + s.substring(0, 4);
  300.         tempS += "10" +  s.substring(4, 10);
  301.         tempS += "10" + s.substring(10,16);
  302.         var sss = "0123456789ABCDEF";
  303.         for(var i = 0; i < 3; i ++)
  304.         {
  305.             retS += "%";
  306.             ss = tempS.substring(i * 8, (eval(i)+1)*8);
  307.  
  308.             retS += sss.charAt(BartUtils.dig2Dec(ss.substring(0,4)));
  309.             retS += sss.charAt(BartUtils.dig2Dec(ss.substring(4,8)));
  310.         }
  311.         return retS;
  312.     }
  313.     return "";
  314. };
  315.  
  316. BartUtils.UTF8Encode = function(s1)
  317. {
  318.     var s = escape(s1);
  319.     var sa = s.split("%");
  320.     var retV ="";
  321.     if(sa[0] != "")
  322.     {
  323.         retV = sa[0];
  324.     }
  325.     for(var i = 1; i < sa.length; i ++)
  326.     {
  327.         if(sa[i].substring(0,1) == "u")
  328.         {
  329.             retV += BartUtils.hex2Utf8(BartUtils.str2Hex(sa[i].substring(1,5)));
  330.  
  331.         }
  332.         else retV += "%" + sa[i];
  333.     }
  334.  
  335.     return retV;
  336. };
  337. */
  338.  
  339. BartUtils.Base64 = {
  340.  
  341.    // private property
  342.    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  343.  
  344.    encode: function(input)
  345.    {
  346.        var output = "";
  347.        var byteBuffer;
  348.        var encodedCharIndexes = new Array(4);
  349.        var i = 0;
  350.        var j;
  351.        var paddingBytes = 0;
  352.  
  353.        while(i < input.length)
  354.        {
  355.            // Fill byte buffer array
  356.            byteBuffer = new Array(3);
  357.            for(j = 0; j < byteBuffer.length; j++)
  358.                if(i < input.length)
  359.                    byteBuffer[j] = input.charCodeAt(i++) & 0xff; // throw away high-order byte, as documented at: https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
  360.            else
  361.                byteBuffer[j] = 0;
  362.  
  363.            // Get each encoded character, 6 bits at a time
  364.            // index 1: first 6 bits
  365.            encodedCharIndexes[0] = byteBuffer[0] >> 2;
  366.            // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)
  367.            encodedCharIndexes[1] = ((byteBuffer[0] & 0x3) << 4) | (byteBuffer[1] >> 4);
  368.            // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)
  369.            encodedCharIndexes[2] = ((byteBuffer[1] & 0x0f) << 2) | (byteBuffer[2] >> 6);
  370.            // index 3: forth 6 bits (6 least significant bits from input byte 3)
  371.            encodedCharIndexes[3] = byteBuffer[2] & 0x3f;
  372.  
  373.            // Determine whether padding happened, and adjust accordingly
  374.            paddingBytes = i - (input.length - 1);
  375.            switch(paddingBytes){
  376.                case 2:
  377.                    // Set last 2 characters to padding char
  378.                    encodedCharIndexes[3] = 64;
  379.                    encodedCharIndexes[2] = 64;
  380.                    break;
  381.                case 1:
  382.                    // Set last character to padding char
  383.                    encodedCharIndexes[3] = 64;
  384.                    break;
  385.                default:
  386.                    break; // No padding - proceed
  387.            }
  388.            // Now we will grab each appropriate character out of our keystring
  389.            // based on our index array and append it to the output string
  390.            for(j = 0; j < encodedCharIndexes.length; j++)
  391.                output += this._keyStr.charAt(encodedCharIndexes[j]);
  392.        }
  393.        return output;
  394.    }
  395. };